#!/bin/bash
exec >trafficgen-client-stderrout.txt
exec 2>&1

. /usr/bin/trafficgen-base || (echo "/usr/bin/trafficgen-base not found"; exit 1)

dump_runtime
validate_label

# defaults
sample_dir=`/bin/pwd`
traffic_generator=trex-txrx # TODO: get trex-txrx-profile to be the default
devices=""
active_devices=""
device_pairs_opt="" # The device IDs to pass to binary-search.  If empty, binary-search assumes 0 and 1
passthru_args=()
re='^(--[^=]+)=([^=]+)'
while [ $# -gt 0 ]; do
    if [[ "$1" =~ $re ]]; then
        arg="${BASH_REMATCH[1]}"
        val="${BASH_REMATCH[2]}"
        shift
    else
        arg="$1"
        shift
        val="$1"
        shift
    fi
    case "$arg" in
        # The following two are needed to determine DPDK device IDs (0,1,2...)
        --active-devices)
            active_devices="$val"
            ;;
        --devices)
            devices="$val"
            ;;
        # Skip options not intended for binary-search
        --cpus|--mem-limit)
            ;;
        # All other options should be supported natively by binary-search
        *)
            passthru_args+=("$arg")
            passthru_args+=("$val")
            ;;
    esac
done
if [ -z "$active_devices" ]; then
    active_devices="$devices"
fi

# Trafficgen-client might need MAC info from the server (testpmd)
echo "These files exist in ./msgs/rx:"
/bin/ls -l msgs/rx
file="msgs/rx/endpoint-start:1"
echo
cat $file
echo
if [ -e "$file" ]; then
    echo "Found $file"
    dstmac0=`jq -r '.macs[0]' $file`
    if [ ! -z "$dstmac0" ]; then
        echo "Found MAC0 $dstmac0"
    fi
    dstmac1=`jq -r '.macs[1]' $file`
    if [ ! -z "$dstmac1" ]; then
        echo "Found MAC1 $dstmac1"
    fi
    if [ ! -z "$dstmac0" -a ! -z "$dstmac1" ]; then
        passthru_args+=(" --dst-macs=$dstmac0,$dstmac1")
    fi
fi

# Map the PCI device locations to logical DPDK IDs
# If no devices are defined, it is assumed that 
# trafficgen-infra has autodetected 2 devices, and they
# are the only 2 set up for DPDK, and will be device IDs
# 0 and 1.
if [ ! -z "$devices" ]; then
    total_devices=$(echo $devices | sed -e "s/,/ /g" | wc -w)
    #if [ $(echo "${total_devices} % 2" | bc) != 0 ]; then
    if [ $(($total_devices % 2)) != 0 ]; then
        exit_error "devices must be supplied in quantities of 2" 1 "$sample_dir"
    else
        #total_device_pairs=$(echo "${total_devices} / 2" | bc)
        total_device_pairs=$(($total_devices / 2))
        if [ $traffic_generator == "trex-txrx" -o $traffic_generator == "trex-txrx-profile" ]; then
            device_pair_index=0
            device_pairs_opt+=" --device-pairs="
            for device in $(seq 1 2 ${total_devices}); do
                device_a=$(( device - 1))
                device_b=${device}
                device_pairs_opt+="${device_a}:${device_b}"
                (( device_pair_index++ ))
                if [ ${device_pair_index} -lt ${total_device_pairs} ]; then
                    device_pairs_opt+=","
                fi
            done
        else
            if [ "${total_device_pairs}" -gt 1 ]; then
                exit_error "only the trex-txrx* traffic generators support more than 1 pair of devices" 1 "$sample_dir"
            fi
        fi
    fi
    total_active_devices=$(echo ${active_devices} | sed -e "s/,/ /g" | wc -w)
    if [ $(($total_active_devices % 2)) -ne 0 ]; then
        exit_error "active devices must be supplied in quantities of 2" 1 "$sample_dir"
    else
        if [ $traffic_generator != "trex-txrx" -a \
             $traffic_generator != "trex-txrx-profile" -a \
             "${devices}" != "${active_devices}" ]; then
            exit_error "only the trex-txrx* traffic generators support --client-devices != --active-client-devices" 1 "$sample_dir"
        else
            if [ $traffic_generator == "trex-txrx" -o $traffic_generator == "trex-txrx-profile" ]; then
                active_device_pair_index=0
                device_pairs_opt+=" --active-device-pairs="
                active_device_state=0
                active_devices_processed=0
                for active_device in `echo $active_devices | sed -e s/,/" "/g`; do
                    device_index=0
                    active_device_index=-1
                    for device in `echo $devices | sed -e s/,/" "/g`; do
                        if [ "${device}" == "${active_device}" ]; then
                            active_device_index=${device_index}
                        fi
                        (( device_index++ ))
                    done
                    (( active_devices_processed++ ))
                    if [ ${active_device_index} -ne -1 ]; then
                        if [ ${active_device_state} -eq 0 ]; then
                            device_pairs_opt+="${active_device_index}:"
                            (( active_device_state++ ))
                        elif [ ${active_device_state} -eq 1 ]; then
                            device_pairs_opt+="${active_device_index}"
                            active_device_state=0
                            if [ ${active_devices_processed} -lt ${total_active_devices} ]; then
                                device_pairs_opt+=","
                            fi
                        fi
                    else
                        exit_error "Couldn't find an active device [${active_device}] in the list of devices [${devices}]" 1 "$sample_dir"
                    fi
                done
            fi
        fi
    fi
fi


if [ -z "$(command -v binary-search.py)" ]; then
    exit_error "ERROR: binary-search.py is missing" 1 "$sample_dir"
fi
if [ ! -e /usr/bin/python3 ]; then
    exit_error "can't find /usr/bin/python3, exiting" 1 "$sample_dir"
fi

cmd="binary-search.py ${passthru_args[@]} --output-dir $sample_dir $device_pairs_opt"
echo "About to run: $cmd"
$cmd >$sample_dir/binary-search.txt 2>&1
bs_rc=$?

if [ "$endpoint" == "k8s" -a "$osruntime" == "pod" ]; then
    # Don't shutdown TRex, as we can't remove the hugepages in /dev/hugepages after
    # when using a pod.
    exit 0
fi

if [ -e $sample_dir/trex-server-running.txt ]; then
    echo "Skipping TRex shutdown since I did not start it"
else
    echo "Shutting down TRex"
    pid_file="$sample_dir/trex-server-pid.txt"
    if [ ! -e $pid_file ]; then
	exit_error "[ERROR] could not find TRex pid file: $pid_file" 1 "$sample_dir"
	exit 1
    fi
    pid=`cat $pid_file`
    if [ ! -z "$pid" ]; then
	kill -s SIGINT $pid || kill -s SIGTERM $pid
	rc=$?
	if [ $rc -gt 0 ]; then
            exit_error "kill of TRex pid $pid failed" $rc "$sample_dir"
	fi
    else
	exit_error "[ERROR] could not find TRex PID in $pid_file" 1 "$sample_dir"
    fi
fi

if [ $bs_rc != 0 ]; then
    error=`grep -E ERROR\|critical $sample_dir/binary-search.txt`
    exit_error "binary-search.py failed:\n$error" 1 "$sample_dir"
fi
